﻿
Namespace std
    'the queue will fail if the count of elements is over _MAX_SIZE
    'so only for a critical performance requirement
    Public Structure fixed_queue(Of T, _MAX_SIZE As _int64)
        Private Shared ReadOnly MAX_SIZE As Int64 = 0
        Private Shared ReadOnly MAX_SIZE_D_1 As Int64 = 0

        Private q() As T
        Private start As Int64
        Private last As Int64

        Shared Sub New()
            MAX_SIZE_D_1 = +(alloc(Of _MAX_SIZE)())
            MAX_SIZE = MAX_SIZE_D_1 + 1
            assert([default](Of T())() Is Nothing)
            assert([default](Of Int64)() = 0)
        End Sub

        Private Sub create()
            If q Is Nothing Then
                ReDim q(MAX_SIZE_D_1)
                assert(Not q Is Nothing)
            End If
        End Sub

        Private Sub inc(ByRef i As Int64)
            i += 1
            If i = MAX_SIZE Then
                i = 0
            End If
        End Sub

        Public Sub push(ByVal i As T)
            create()
            q(last) = i
            inc(last)
        End Sub

        Public Function size() As Int64
            Dim rtn As Int64 = 0
            rtn = last - start
            If rtn < 0 Then
                rtn += MAX_SIZE_D_1
            End If
            Return rtn
        End Function

        Public Function full() As Int64
            Return size() = MAX_SIZE_D_1
        End Function

        Public Function empty() As Boolean
            Return size() = 0
        End Function

        Public Function pop() As T
            Dim r As T = Nothing
            If empty() Then
                r = Nothing
            Else
                r = q(start)
                q(start) = Nothing
                inc(start)
            End If
            Return r
        End Function

        Public Sub clear()
            start = 0
            last = 0
            memclr(q)
        End Sub
    End Structure
End Namespace
